#include <stack>
#include <vector>
#include <utility>
#include <iostream>
using namespace std;
class Solution
{
private:
    // 传入有边界 获取值,出栈,找左边界,返回面积
    int get_bar_size(stack<pair<int, int>> &st, int r)
    {
        if (st.empty())
            return 0;
        int val = st.top().first;
        st.pop();
        int l = st.empty() ? 0 : st.top().second + 1;
        return (r - l) * val;
    }
    // 遍历:每个节点都作为左边界入栈,找右边界,找到就计算面积并出栈,然后右边界作为左边界入栈 如此循环
    int max_bar(const vector<int> &heights)
    {
        int res = 0;
        if (heights.size() == 0)
            return res;
        stack<pair<int, int>> st;
        st.push({heights[0], 0});
        for (int i = 1; i < heights.size(); i++)
        {
            while (!st.empty() && heights[i] < st.top().first)
            {
                res = max(res, get_bar_size(st, i));
            }
            st.push({heights[i], i});
        }
        while (!st.empty())
        {
            res = max(res, get_bar_size(st, heights.size()));
        }
        return res;
    }

public:
    // 以层为单位遍历 把每层开始从第一个往上连续的方块转换为直方图 这样就枚举了所有矩形 计算每层 更新答案
    int maximalRectangle(vector<string> &matrix)
    {
        if (matrix.size() == 0)
            return 0;
        int res = 0;
        vector<int> heights(matrix[0].size(), 0);
        for (auto &e : matrix)
        {
            for (int i = 0; i < e.size(); i++)
            {
                if (e[i] == '0')
                    heights[i] = 0;
                else
                    heights[i]++;
            }
            res = max(max_bar(heights), res);
        }
        return res;
    }
};